/**
  ****************************(C) COPYRIGHT 2019 DJI****************************
  * @file       can_receive.c/h
  * @brief      there is CAN interrupt function  to receive motor data,
  *             and CAN send function to send motor current to control motor.
  *             锟斤拷锟斤拷锟斤拷CAN锟叫断斤拷锟秸猴拷锟斤拷锟斤拷锟斤拷锟秸碉拷锟斤拷锟斤拷锟�,CAN锟斤拷锟酵猴拷锟斤拷锟斤拷锟酵碉拷锟斤拷锟斤拷锟斤拷锟斤拷频锟斤拷.
  * @note
  * @history
  *  Version    Date            Author          Modification
  *  V1.0.0     Dec-26-2018     RM              1. done
  *
  @verbatim
  ==============================================================================

  ==============================================================================
  @endverbatim
  ****************************(C) COPYRIGHT 2019 DJI****************************
  */

#ifndef CAN_RECEIVE_H
#define CAN_RECEIVE_H

#ifdef __cplusplus
extern "C"
{
#endif
#define RATE_BUF_SIZE 6
#include "struct_typedef.h"
#include "FreeRTOS.h"
#include "queue.h"
#define CHASSIS_CAN hcan1
#define GIMBAL_CAN hcan2
  typedef union
  {
    float fdata;
    uint8_t udata[4];
  } CAN_DataTypeConvert;
  extern CAN_DataTypeConvert CAN_Data;
  extern float Can_RxData[2];
  /* CAN send and receive ID */
  typedef enum
  {
    // CAN1鎺у埗澶�
    //  Pitch浜戝彴
    CAN_Pitch_6020_ID = 0X2FF,    // 鏍囪瘑绗� Pitch浜戝彴 鐢靛帇鎺у埗
                                  // 鍙嶉鎶ユ枃ID
    CAN_Pitch_6020_M1_ID = 0x20A, // ID=6
                                  // 寮€鐏�3508鐢垫満
    CAN_FIRE_3508_ID = 0x200,     // 鏍囪瘑绗� 寮€鐏�3508鐢垫満
                                  // 鍙嶉鎶ユ枃ID
    CAN_FIRE_3508_M1_ID = 0x202,  // ID=2
    CAN_FIRE_3508_M2_ID = 0x203,  // ID=3

    // CAN2鎺ュ彈A鏉垮彂鏉ョ殑淇℃伅
    BoardA_Message_ID = 0x200,
    SendMsg_to_BoardA_ID = 0x199,

  } can_msg_id_e;

  // rm motor data
  typedef struct
  {
    int32_t speed_rpm;               // 锟斤拷锟阶拷锟阶拷锟�
    int32_t avg_rate;                // 锟斤拷锟斤拷锟斤拷锟斤拷转锟斤拷平锟斤拷锟劫讹拷
    int32_t given_current;           // 锟斤拷锟斤拷锟斤拷锟斤拷
    int32_t temperate;               // 锟铰讹拷
    int32_t raw_ecd;                 // 未锟斤拷锟斤拷实时锟斤拷锟斤拷abs angle range:[0,8191]
    int32_t last_raw_ecd;            // 未锟斤拷锟斤拷锟较次憋拷锟斤拷abs angle range:[0,8191]
    int32_t deal_ecd;                // 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟�
    int32_t ecd_diff;                // 锟斤拷锟轿憋拷锟斤拷之锟斤拷锟街�
    int32_t ecd_raw_rate;            // 通锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷玫锟斤拷谋锟斤拷锟斤拷俣锟皆贾�
    float ecd_angle;                 // 锟斤拷锟斤拷锟桔伙拷锟角讹拷
    int32_t ecd_bias;                // 锟斤拷始锟斤拷锟斤拷锟斤拷值
    int32_t buf_count;               // 锟剿诧拷锟斤拷锟斤拷buf锟斤拷
    int32_t rate_buf[RATE_BUF_SIZE]; // buf锟斤拷for filter
    int32_t round_cnt;               // 目前圈锟斤拷
    float speed;
    float distance;
    long long Angle_actual;
    int16_t offset_angle;
    int16_t angle;
    int16_t last_angle;

  } Motor_Measure_T;

  extern Motor_Measure_T motor_chassis[8];
  /**
   * @brief          send control current of motor (0x205, 0x206, 0x207, 0x208)
   * @param[in]      yaw: (0x205) 6020 motor control current, range [-30000,30000]
   * @param[in]      pitch: (0x206) 6020 motor control current, range [-30000,30000]
   * @param[in]      shoot: (0x207) 2006 motor control current, range [-10000,10000]
   * @param[in]      rev: (0x208) reserve motor control current
   * @retval         none
   */
  /**
   * @brief          锟斤拷锟酵碉拷锟斤拷锟斤拷频锟斤拷锟�(0x205,0x206,0x207,0x208)
   * @param[in]      yaw: (0x205) 6020锟斤拷锟斤拷锟斤拷频锟斤拷锟�, 锟斤拷围 [-30000,30000]
   * @param[in]      pitch: (0x206) 6020锟斤拷锟斤拷锟斤拷频锟斤拷锟�, 锟斤拷围 [-30000,30000]
   * @param[in]      shoot: (0x207) 2006锟斤拷锟斤拷锟斤拷频锟斤拷锟�, 锟斤拷围 [-10000,10000]
   * @param[in]      rev: (0x208) 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷频锟斤拷锟�
   * @retval         none
   */
  extern void CAN_cmd_gimbal(int16_t yaw, int16_t pitch, int16_t shoot, int16_t rev);

  /**
   * @brief          send CAN packet of ID 0x700, it will set chassis motor 3508 to quick ID setting
   * @param[in]      none
   * @retval         none
   */
  /**
   * @brief          锟斤拷锟斤拷ID为0x700锟斤拷CAN锟斤拷,锟斤拷锟斤拷锟斤拷锟斤拷3508锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷ID
   * @param[in]      none
   * @retval         none
   */
  extern void CAN_cmd_chassis_reset_ID(void);

  /**
   * @brief          send control current of motor (0x201, 0x202, 0x203, 0x204)
   * @param[in]      motor1: (0x201) 3508 motor control current, range [-16384,16384]
   * @param[in]      motor2: (0x202) 3508 motor control current, range [-16384,16384]
   * @param[in]      motor3: (0x203) 3508 motor control current, range [-16384,16384]
   * @param[in]      motor4: (0x204) 3508 motor control current, range [-16384,16384]
   * @retval         none
   */
  /**
   * @brief          锟斤拷锟酵碉拷锟斤拷锟斤拷频锟斤拷锟�(0x201,0x202,0x203,0x204)
   * @param[in]      motor1: (0x201) 3508锟斤拷锟斤拷锟斤拷频锟斤拷锟�, 锟斤拷围 [-16384,16384]
   * @param[in]      motor2: (0x202) 3508锟斤拷锟斤拷锟斤拷频锟斤拷锟�, 锟斤拷围 [-16384,16384]
   * @param[in]      motor3: (0x203) 3508锟斤拷锟斤拷锟斤拷频锟斤拷锟�, 锟斤拷围 [-16384,16384]
   * @param[in]      motor4: (0x204) 3508锟斤拷锟斤拷锟斤拷频锟斤拷锟�, 锟斤拷围 [-16384,16384]
   * @retval         none
   */
  // extern void CAN_cmd_chassis(int16_t motor1, int16_t motor2, int16_t motor3, int16_t motor4, int16_t motor5, int16_t motor6, int16_t motor7, int16_t motor8);
  // extern void CAN_cmd_4_chassis(int16_t motor1, int16_t motor2, int16_t motor3, int16_t motor4);
  void CAN_Send_Fire_cmd(int16_t motor1, int16_t motor2);
  void CAN_Send_Pitch_cmd(int16_t motor1);

  /**
   * @brief          return the yaw 6020 motor data point
   * @param[in]      none
   * @retval         motor data point
   */
  /**
   * @brief          锟斤拷锟斤拷yaw 6020锟斤拷锟斤拷锟斤拷锟街革拷锟�
   * @param[in]      none
   * @retval         锟斤拷锟斤拷锟斤拷锟街革拷锟�
   */
  // extern const motor_measure_t *get_yaw_gimbal_motor_measure_point(void);

  /**
   * @brief          return the pitch 6020 motor data point
   * @param[in]      none
   * @retval         motor data point
   */
  /**
   * @brief          锟斤拷锟斤拷pitch 6020锟斤拷锟斤拷锟斤拷锟街革拷锟�
   * @param[in]      none
   * @retval         锟斤拷锟斤拷锟斤拷锟街革拷锟�
   */
  // extern const motor_measure_t *get_pitch_gimbal_motor_measure_point(void);

  /**
   * @brief          return the trigger 2006 motor data point
   * @param[in]      none
   * @retval         motor data point
   */
  /**
   * @brief          锟斤拷锟截诧拷锟斤拷锟斤拷锟� 2006锟斤拷锟斤拷锟斤拷锟街革拷锟�
   * @param[in]      none
   * @retval         锟斤拷锟斤拷锟斤拷锟街革拷锟�
   */
  // extern const motor_measure_t *get_trigger_motor_measure_point(void);

  /**
   * @brief          return the chassis 3508 motor data point
   * @param[in]      i: motor number,range [0,3]
   * @retval         motor data point
   */
  /**
   * @brief          锟斤拷锟截碉拷锟教碉拷锟� 3508锟斤拷锟斤拷锟斤拷锟街革拷锟�
   * @param[in]      i: 锟斤拷锟斤拷锟斤拷,锟斤拷围[0,3]
   * @retval         锟斤拷锟斤拷锟斤拷锟街革拷锟�
   */
  extern const Motor_Measure_T *get_chassis_motor_measure_point(uint8_t i);
  void get_BoardA_message(uint8_t *rxdata);
  void CAN_Send_BoardA(uint8_t *data);
#ifdef __cplusplus
}
#endif

#endif
